package com.atguigu.tingshu.account.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.atguigu.tingshu.account.mapper.UserAccountDetailMapper;
import com.atguigu.tingshu.account.mapper.UserAccountMapper;
import com.atguigu.tingshu.account.service.UserAccountService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.model.account.UserAccount;
import com.atguigu.tingshu.model.account.UserAccountDetail;
import com.atguigu.tingshu.vo.account.AccountLockResultVo;
import com.atguigu.tingshu.vo.account.AccountLockVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.math.BigDecimal;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserAccountServiceImpl extends ServiceImpl<UserAccountMapper, UserAccount> implements UserAccountService {

	@Autowired
	private UserAccountMapper userAccountMapper;
	@Autowired
	private UserAccountDetailMapper userAccountDetailMapper;

	@Override
	public void saveUserAccount(Long obj) {
		UserAccount userAccount = new UserAccount();

		//1.创建账户对象，新增账户
		userAccount.setUserId(obj);
		userAccount.setTotalAmount(new BigDecimal("100"));
		userAccount.setAvailableAmount(new BigDecimal("100"));
		userAccount.setTotalIncomeAmount(new BigDecimal("100"));
		userAccountMapper.insert(userAccount);
		//2.新增账户变动历史（首次注册赠送100点）
		if (userAccount.getAvailableAmount().intValue() > 0) {
			this.saveUserAccountDetail(obj, "赠送", SystemConstant.ACCOUNT_TRADE_TYPE_DEPOSIT, userAccount.getAvailableAmount(), null);
		}
	}

	@Override
	public BigDecimal getAvailableAmount(Long userId) {
		UserAccount userAccount = userAccountMapper.selectById(userId);
		Assert.notNull(userAccount,"用户："+userId+"不存在");
		return userAccount.getAvailableAmount();
	}

	@Override
	public AccountLockResultVo checkAndLock(AccountLockVo accountLockVo) {
		UserAccount userAccount = userAccountMapper.selectOne(new LambdaQueryWrapper<UserAccount>().eq(UserAccount::getUserId, accountLockVo.getUserId()));
		BigDecimal lockAmount = userAccount.getLockAmount();
		BigDecimal totalAmount = userAccount.getTotalAmount();
		lockAmount = lockAmount.add(accountLockVo.getAmount());
		if (lockAmount.compareTo(totalAmount)>0){
			throw new GuiguException(500,"用户余额不足");
		}
//		userAccount.setLockAmount(lockAmount); 由于未实现微信支付接口 制作假数据 无需锁定余额 直接扣减
		userAccount.setTotalAmount(userAccount.getTotalAmount().subtract(accountLockVo.getAmount()));
		userAccount.setTotalPayAmount(userAccount.getTotalPayAmount().add(accountLockVo.getAmount()));
		userAccount.setAvailableAmount(userAccount.getAvailableAmount().subtract(accountLockVo.getAmount()));
		userAccountMapper.updateById(userAccount);
		AccountLockResultVo resultVo = BeanUtil.copyProperties(accountLockVo, AccountLockResultVo.class);
		return resultVo;
	}

	@Override
	public void updateAccount(AccountLockVo accountLockVo) {
		UserAccount userAccount = userAccountMapper.selectOne(new LambdaQueryWrapper<UserAccount>().eq(UserAccount::getUserId, accountLockVo.getUserId()));
		//基于未实现微信支付接口的实现 所以假装支付成功 锁定方法不使用 直接扣减
		BigDecimal availableAmount = userAccount.getAvailableAmount();
		if (availableAmount.compareTo(accountLockVo.getAmount())<0){
			throw new GuiguException(500,"用户余额不足");
		}
		userAccount.setAvailableAmount(availableAmount.subtract(accountLockVo.getAmount()));
		userAccount.setTotalAmount(userAccount.getTotalAmount().subtract(accountLockVo.getAmount()));
		userAccountMapper.updateById(userAccount);
		this.saveUserAccountDetail(accountLockVo.getUserId(),accountLockVo.getContent(),SystemConstant.ACCOUNT_TRADE_TYPE_LOCK,accountLockVo.getAmount(),accountLockVo.getOrderNo());
	}

	/**
	 * 检查及扣减账户余额；增加账户变动日志
	 *
	 * @param accountDeductVo
	 */
//	@Override
//	@Transactional(rollbackFor = Exception.class)
//	public void checkAndDeduct(AccountLockVo accountLockVo) {
//		//1.检查及扣减余额
//		int count = userAccountMapper.checkAndDeduct(accountLockVo.getUserId(), accountLockVo.getAmount());
//		if (count == 0) {
//			throw new GuiguException(400, "账户余额不足！");
//		}
//		//2.新增账户变动日志
//		this.saveUserAccountDetail(
//				accountLockVo.getUserId(),
//				accountLockVo.getContent(),
//				SystemConstant.ACCOUNT_TRADE_TYPE_MINUS,
//				accountLockVo.getAmount(),
//				accountLockVo.getOrderNo()
//		);
//	}

	/**
	 * 新增账户变动日志
	 * @param userId 用户ID
	 * @param title 资金变动缘由
	 * @param tradeType 交易类型
	 * @param amount 变动金额
	 * @param orderNo 订单编号
	 */
	private void saveUserAccountDetail(Long userId, String title, String tradeType, BigDecimal amount, String orderNo) {
		UserAccountDetail userAccountDetail = new UserAccountDetail();
		userAccountDetail.setUserId(userId);
		userAccountDetail.setTitle(title);
		userAccountDetail.setTradeType(tradeType);
		userAccountDetail.setAmount(amount);
		userAccountDetail.setOrderNo(orderNo);
		userAccountDetailMapper.insert(userAccountDetail);
	}

}
